package com.hotel.customersystem.controller;



import com.common.status.ResultMsg;
import com.common.status.StatusCode;
import com.common.utils.ResultUtils;
import com.common.utils.ResultVo;
import com.hotel.config.rabbitmq.config.PersonalCouponCancelDirectConfig;
import com.hotel.config.rabbitmq.config.PersonalCouponWebSocketDirectConfig;
import com.hotel.customersystem.pojo.CustomerUserCoupon;
import com.hotel.customersystem.service.CustomerUserCouponService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * (CustomerUserCoupon)表控制层
 *
 * @author makejava
 * @since 2022-09-30 16:33:50
 */
@Api(value = "CustomerUserController",tags = {"个人中心优惠券模块"})
@RestController
@RequestMapping("customerUserCoupon")
public class CustomerUserCouponController  {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private CustomerUserCouponService customerUserCouponService;

    @Resource
    private RedisTemplate<String,List<CustomerUserCoupon>> redisTemplate;

    /**
     * 返回单张用户优惠卷的用户id
     * @param couponId
     * @return
     */
    @GetMapping("/getUserId")
    public String getCustomerUserId(Integer couponId){
        CustomerUserCoupon coupon = customerUserCouponService.getById(couponId);
        return String.valueOf(coupon.getUserId());
    }

    /**
     * 用户未登录时，优惠劵将要过期提醒websocket消息存入到redis当中
     */
    @PostMapping("/saveWebSocketRedis")
    public String saveWebSocketRedis(@RequestBody Map mapMessage){
        String userId = (String) mapMessage.get("userId");
        String message = (String) mapMessage.get("message");
        System.out.println("用户id: "+userId);
        System.out.println("用户消息: "+message);
        return customerUserCouponService.saveWebSocketRedis(userId,message);
    }

    /**
     * 用户登录后 从 redis 当中读取未推送数据重新进行推送
     */
    @GetMapping("/getRedisToWebSocket/{userId}")
    public Boolean getRedisToWebSocket(@PathVariable("userId") String userId){
        return customerUserCouponService.getRedisToWebSocket(userId);
    }

    @ApiOperation(value = "个人中心优惠券列表")
    @GetMapping("/getCustomerCouponList")
    public ResultVo<List<CustomerUserCoupon>> getCustomerUserList() {
        List<CustomerUserCoupon> list = customerUserCouponService.list();
        if (list.size()!=0) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.ERROR_MSG, StatusCode.SYSTEM_ERROR_CODE,list);
    }

    /**
     * 个人中心用户个人的优惠券库存表
     * @param userAdmin
     * @return
     */
    @ApiOperation(value = "个人中心用户个人的优惠券列表")
    @GetMapping("/getByUserAdmin")
    public ResultVo<List<CustomerUserCoupon>> getByUserId(@RequestParam(value = "userAdmin") String userAdmin) {
        List<CustomerUserCoupon> list = selectCouponByUserAdmin(userAdmin);
//        // 1.判断是否有该缓存数据
//        List<CustomerUserCoupon> redisCouponList = redisTemplate.boundValueOps("myCouponList").get();
//        if (redisCouponList == null) {
//            // 调用封装的查询方法
//            list = selectCouponByUserAdmin(userAdmin);
//        }
//        // 2.如果在缓存中，接着判断缓存中的优惠券数据是否已过期
//        else {
//            List<CustomerUserCoupon> userCoupons = redisCouponList.stream().filter(s -> s.getInvalidTime().isAfter(LocalDateTime.now())).collect(Collectors.toList());
//            if (userCoupons.size()>0) { // 说明有过期的优惠券，需要重新查询数据库
//                list = selectCouponByUserAdmin(userAdmin);
//            }
//        }
        if (list.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL,StatusCode.SYSTEM_ERROR_CODE,list);
    }

    /**
     * 个人中心使用优惠券后修改优惠券记录
     */
    @ApiOperation(value = "修改个人中心优惠券使用状态")
    @PutMapping("/updateCouponByCounponNo")
    public ResultVo<String> updateCouponByCounponNo(@RequestParam(value = "couponNo") Integer couponNo) {
        // 1.修改优惠券使用状态
        Boolean flag = customerUserCouponService.updateCouponByCouponNo(couponNo);
        if (flag) {
            // 判断redis中是否有该key
            if (isExistRedisKey("myCouponList")) {
                // 删除key
                redisTemplate.delete("myCouponList");
            }
            return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,true);
        }
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,false);
    }

    /**
     * 查询个人中心里的优惠券记录
     * @param userAdmin
     * @return
     */
    public List<CustomerUserCoupon> selectCouponByUserAdmin(String userAdmin) {
        // 查询数据
        List<CustomerUserCoupon> list = customerUserCouponService.getByUserAdmin(userAdmin);
        // 设置到缓存中
        if (list.size() != 0) {
            redisTemplate.boundValueOps("myCouponList").set(list);
            redisTemplate.boundValueOps("myCouponList").expire(7, TimeUnit.DAYS); // 设置过期时间7天
        }
        return list;
    }

    /**
     * 判断redis缓存中是否有该key
     * @param redisKey
     * @return
     */
    public Boolean isExistRedisKey(String redisKey) {
        return redisTemplate.hasKey(redisKey);
    }

    /**
     * 插入优惠券
     * @param coupon
     * @return
     */
    @ApiOperation(value = "插入优惠券")
    @PostMapping("/addCoupon")
    public ResultVo<Boolean> addCoupon(@RequestBody CustomerUserCoupon coupon) {
        boolean flag = customerUserCouponService.save(coupon);
        if (flag) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,flag);
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,flag);
    }

    /**
     * <=======测试版本=========></=======测试版本=========>
     * 将个人优惠劵过期时间存放到消息队列当中(提前三天)
     * 1.获取提醒的时间 计算出前面三天的日期
     * 2.死信队列当中调用 websocket 对用户进行提醒 ----------------------> 马勇春对接此接口 个人优惠劵放入消息队列 ^ v ^ 用完记得删箭头内容
     */
    @PostMapping("/savePersonCouponToQueue/{id}")
    public String savePersonCouponWebSocket(@PathVariable("id") String couponId){
        //测试版本
        CustomerUserCoupon customerUserCoupon = customerUserCouponService.getById(couponId);
        //1.获取提醒的时间 计算出前面三天的日期(单位:毫秒)
        LocalDateTime createTime = customerUserCoupon.getReceiveTime();
        LocalDateTime invalidTime = customerUserCoupon.getInvalidTime();
        System.out.println("开始使用时间:"+createTime);
        System.out.println("过期使用时间:"+invalidTime);
        Duration duration = Duration.between(createTime, invalidTime);
        long days = duration.toDays() - 3;
//        String cancelTime = String.valueOf(days * 24 * 60 * 60 * 1000);
        String cancelTime = "2000";
        //测试代码(测试)
        System.out.println("优惠劵使用天数:"+days);
        System.out.println("优惠劵提醒时间:"+cancelTime);
        //设置单个信息过期时间
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration(cancelTime);
        Message message = new Message(couponId.getBytes(), messageProperties);
        rabbitTemplate.convertAndSend(PersonalCouponWebSocketDirectConfig.NORMAL_PERSON_COUPON_WEBSOCKET_EXCHANGE,
                PersonalCouponWebSocketDirectConfig.NORMAL_PERSON_COUPON_WEBSOCKET_KEY,message);
        return "消息已经放入websocket消息队列";
    }

    /**
     * rabbitmq重新入队进行监听，所有消息过期时间均为三天(bug:时间失效)
     * 三天到则优惠劵过期
     * @param couponId 优惠劵id
     */
    @PostMapping("/rabbitListenIsCancel/{id}")
    public String rabbitListenIsCancel(@PathVariable("id") String couponId){
        System.out.println("优惠劵重新进入过期队列:"+couponId);
        String time = String.valueOf(3 * 24 * 60 * 60 * 1000);
        //测试数据
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration(time);
        Message message = new Message(couponId.getBytes(),messageProperties);
        rabbitTemplate.convertAndSend(PersonalCouponCancelDirectConfig.NORMAL_PERSON_COUPON_CANCEL_EXCHANGE,
                PersonalCouponCancelDirectConfig.NORMAL_PERSON_COUPON_CANCEL_KEY,message);
        return "消息已经放入(优惠劵过期)消息队列";
    }

    @GetMapping("/notUseCouponList/{userId}")
    public ResultVo<List<CustomerUserCoupon>> getCouponList(@PathVariable("userId") Integer userId){
        List<CustomerUserCoupon> list = customerUserCouponService.getByUserIdNotUse(userId);
        if (list!=null) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL, StatusCode.SYSTEM_ERROR_CODE,list);
    }
    @GetMapping("/haveUsedCouponList/{userId}")
    public ResultVo<List<CustomerUserCoupon>> getCouponListHaveUsed(@PathVariable("userId") Integer userId){
        List<CustomerUserCoupon> list = customerUserCouponService.getByUserIdHaveUsed(userId);
        if (list!=null) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL, StatusCode.SYSTEM_ERROR_CODE,list);
    }
}

